from datetime import datetime
from typing import Dict, Any, Literal
from enum import Enum
from vnpy.trader.constant import Direction, Offset


class SignalType(Enum):
    """A股交易信号类型，只考虑做多情况"""
    BUY = "买入"      # 买入信号
    SELL = "卖出"     # 卖出信号
    HOLD = "持仓"     # 持仓信号（无操作）


class SignalResult:
    """量化信号结果"""
    
    def __init__(self, symbol: str, strategy_name: str):
        """初始化"""
        self.symbol = symbol                # 股票代码
        self.strategy_name = strategy_name  # 策略名称
        self.datetime = datetime.now()      # 信号生成时间
        self.direction = Direction.LONG     # 信号方向：A股只考虑做多
        self.offset = None                  # 信号开平：Offset.OPEN/Offset.CLOSE
        self.price = 0.0                    # 信号价格
        self.volume = 0                     # 信号数量
        self.signal_type = SignalType.HOLD  # 信号类型，默认为持仓
        
    def __str__(self) -> str:
        """字符串表示"""
        # 根据信号类型返回不同的字符串表示
        if self.signal_type == SignalType.HOLD:
            return f"{self.symbol} {self.strategy_name} {self.datetime} 持仓中 (无操作)"
            
        if self.signal_type == SignalType.BUY:
            return f"{self.symbol} {self.strategy_name} {self.datetime} 买入 {self.price} {self.volume}"
            
        if self.signal_type == SignalType.SELL:
            return f"{self.symbol} {self.strategy_name} {self.datetime} 卖出 {self.price} {self.volume}"
            
        return "信号类型未知"
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典格式"""
        return {
            "symbol": self.symbol,
            "strategy_name": self.strategy_name,
            "datetime": self.datetime.strftime("%Y-%m-%d %H:%M:%S"),
            "direction": "多",  # A股只考虑做多
            "signal_type": self.signal_type.value if isinstance(self.signal_type, SignalType) else "持仓",
            "price": self.price,
            "volume": self.volume,
            "is_valid": self.is_valid()
        }
    
    def is_valid(self) -> bool:
        """检查信号是否有效"""
        # 持仓信号始终有效
        if self.signal_type == SignalType.HOLD:
            return True
            
        # 买入或卖出信号需要有有效价格和数量
        return self.price > 0 and self.volume > 0
        
    def set_buy_signal(self, price: float, volume: int = 100) -> None:
        """设置买入信号"""
        self.signal_type = SignalType.BUY
        self.offset = Offset.OPEN
        self.price = price
        self.volume = volume
        
    def set_sell_signal(self, price: float, volume: int = 100) -> None:
        """设置卖出信号"""
        self.signal_type = SignalType.SELL
        self.offset = Offset.CLOSE
        self.price = price
        self.volume = volume
        
    def set_hold_signal(self) -> None:
        """设置持仓信号（无操作）"""
        self.signal_type = SignalType.HOLD
        self.offset = None
        self.price = 0.0
        self.volume = 0

